package cn.ben3.addondsl.model;

import org.springframework.roo.classpath.details.MethodMetadata;
import org.springframework.roo.classpath.details.MethodMetadataBuilder;
import org.springframework.roo.classpath.details.annotations.AnnotatedJavaType;
import org.springframework.roo.classpath.details.annotations.AnnotationMetadataBuilder;
import org.springframework.roo.classpath.itd.InvocableMemberBodyBuilder;
import org.springframework.roo.model.JavaSymbolName;
import org.springframework.roo.model.JavaType;

import java.util.ArrayList;
import java.util.List;

public class MethodBuilder {
    private MethodMetadataBuilder mb;
    private String declaredbyMetadataId;
    private int modifier;
    private JavaSymbolName methodName;
    private JavaType returnType;
    private List<AnnotationMetadataBuilder> annotations=new ArrayList<AnnotationMetadataBuilder>();
    private List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>();
    private List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>();
    private InvocableMemberBodyBuilder bodyBuilder;
    private List<JavaType> throwsTypes = new ArrayList<JavaType>();



    public MethodBuilder() {

    }
    public MethodBuilder(final String declaredbyMetadataId,
                         final int modifier,
                         final JavaSymbolName methodName, JavaType returnType, InvocableMemberBodyBuilder bodyBuilder) {
        this.declaredbyMetadataId = declaredbyMetadataId;
        this.modifier = modifier;
        this.methodName = methodName;
        this.returnType = returnType;
        this.bodyBuilder = bodyBuilder;

    }
    public MethodBuilder(final String declaredbyMetadataId,
                         final int modifier,
                         final JavaSymbolName methodName, JavaType returnType, final List<AnnotatedJavaType> parameterTypes,
                         final List<JavaSymbolName> parameterNames, InvocableMemberBodyBuilder bodyBuilder) {
        this.declaredbyMetadataId = declaredbyMetadataId;
        this.modifier = modifier;
        this.methodName = methodName;
        this.returnType = returnType;
        this.parameterTypes=parameterTypes;
        this.parameterNames=parameterNames;
        this.bodyBuilder = bodyBuilder;

    }




    public MethodMetadataBuilder builder() {
        //todo
        if(this.mb==null) {
            mb = new MethodMetadataBuilder(declaredbyMetadataId, modifier, methodName, returnType,parameterTypes,parameterNames, bodyBuilder);
            mb.setAnnotations(annotations);
            mb.setThrowsTypes(throwsTypes);
        }
        return this.mb;
    }
    public MethodMetadata build(){
        return this.builder().build();
    }
    public MethodBuilder adTs(JavaType... throwTypes){
        for (JavaType throwType : throwTypes) {
            this.throwsTypes.add(throwType);
        }
        return this;
    }
    public MethodBuilder adAs(AnnotationBuilder... abs){
        for (AnnotationBuilder ab : abs) {
            this.annotations.add(ab.builder());
        }
        return this;
    }
    public List<AnnotatedJavaType> getParameterTypes() {
        return parameterTypes;
    }

    public JavaSymbolName getMethodName() {
        return methodName;
    }
}
